<template>
  <div class="container" ref="container">
    <PropertySetting ref="propertySetting" :node="nodeClick" v-model="processForm" :lf="lf" :disabled="disabled"
      :skipConditionShow="skipConditionShow">
      <template v-slot:[key]="data" v-for="(item, key) in $scopedSlots">
        <slot :name="key" v-bind="data || {}"></slot>
      </template>
    </PropertySetting>
  </div>
</template>

<script>
import LogicFlow from "@logicflow/core";
import "@logicflow/core/dist/style/index.css";
import {Control, DndPanel, Menu, SelectionSelect} from '@logicflow/extension';
import '@logicflow/extension/lib/style/index.css'
import Start from "@/components/WarmFlow/js/start";
import Between from "@/components/WarmFlow/js/between";
import Serial from "@/components/WarmFlow/js/serial";
import Parallel from "@/components/WarmFlow/js/parallel";
import End from "@/components/WarmFlow/js/end";
import Skip from "@/components/WarmFlow/js/skip";
import PropertySetting from '@/components/WarmFlow/PropertySetting/index.vue'
import {saveXml, xmlString} from "@/api/flow/definition";
import {logicFlowJsonToFlowXml, skipText, snakerXml2LogicFlowJson} from "@/components/WarmFlow/js/tool";


export default {
  name: 'design',
  components: {
    PropertySetting,
  },
  data() {
    return {
      lf: null,
      nodeClick: null,
      // 是否禁用表单
      disabled: false,
      processForm: {},
      value: {},
      xmlString: '',
      skipConditionShow: true
    }
  },

  created() {
    this.definitionId = this.$route.params && this.$route.params.id;
    if (this.$route.query.disabled == 'true') {
      this.disabled = true
    }
    // this.value = graphData;
  },
  mounted() {
    this.use();
    this.lf = new LogicFlow({container: this.$refs.container, grid: true,});
    this.register();
    this.initDndPanel();
    this.initControl();
    this.initMenu();
    this.initEvent();
    if (this.definitionId) {
      xmlString(this.definitionId).then(res => {
        this.xmlString = res.data;
        if (this.xmlString) {
          this.value = snakerXml2LogicFlowJson(this.xmlString);
          this.lf.render(this.value);
        }
      });

    }
  },

  methods: {
    /**
     * 初始化拖拽面板
     */
    initDndPanel() {
      this.lf.extension.dndPanel.setPatternItems([
        {
          type: 'start',
          text: '开始',
          label: '开始节点',
          icon: '',
        },
        {
          type: 'between',
          text: '中间节点',
          label: '中间节点',
          icon: '',
          className: 'important-node',
          properties: {}
        },
        {
          type: 'serial',
          text: '',
          label: '互斥网关',
          properties: {},
          icon: '',
        },
        {
          type: 'parallel',
          text: '',
          label: '并行网关',
          properties: {},
          icon: '',
        },
        {
          type: 'end',
          text: '结束',
          label: '结束节点',
          icon: '',
        },
      ]);
    },
    /**
     * 初始化控制面板
     */
    initControl() {
      if (!this.disabled) {
        // 控制面板-清空画布
        this.lf.extension.control.addItem({
          iconClass: 'lf-control-clear',
          title: 'clear',
          text: '清空',
          onClick: (lf, ev) => {
            lf.clearData()
          }
        })
        // 控制面板-清空画布
        this.lf.extension.control.addItem({
          iconClass: 'lf-control-save',
          title: '',
          text: '保存',
          onClick: (lf, ev) => {
            this.graphData = lf.getGraphData()
            this.value['nodes'] = this.graphData['nodes']
            this.value['edges'] = this.graphData['edges']
            console.log("this.value:", this.value)
            let xmlString = logicFlowJsonToFlowXml(this.value);
            console.log("this.xmlString:", xmlString)
            let data = {
              xmlString: xmlString,
              id: this.definitionId
            }
            saveXml(data).then(response => {
              this.$modal.msgSuccess("保存成功");
              if (response.code === 200) {
                this.close();
              }
            });
          }
        });
      }
    },
    /**
     * 初始化菜单
     */
    initMenu() {
      // 为菜单追加选项（必须在 lf.render() 之前设置）
      this.lf.extension.menu.addMenuConfig({
        nodeMenu: [
          {
            text: "属性",
            callback(node) {
              alert(`
          节点id：${node.id}
          节点类型：${node.type}
          节点坐标：(x: ${node.x}, y: ${node.y})
          文本坐标：(x: ${node.text.x}, y: ${node.text.y})`);
            },
          },
        ],
        edgeMenu: [
          {
            text: "属性",
            callback(edge) {
              alert(`
          边id：${edge.id}
          边类型：${edge.type}
          边坐标：(x: ${edge.x}, y: ${edge.y})
          文本坐标：(x: ${edge.text.x}, y: ${edge.text.y})
          源节点id：${edge.sourceNodeId}
          目标节点id：${edge.targetNodeId}`);
            },
          },
        ],
      });
    },
    /**
     * 注册自定义节点和边
     */
    register() {
      this.lf.register(Start);
      this.lf.register(Between);
      this.lf.register(Serial);
      this.lf.register(Parallel);
      this.lf.register(End);
      this.lf.register(Skip);
    },
    /**
     * 添加扩展
     */
    use() {
      LogicFlow.use(DndPanel);
      LogicFlow.use(SelectionSelect);
      LogicFlow.use(Control);
      LogicFlow.use(Menu);
    },
    initEvent() {
      const { eventCenter } = this.lf.graphModel
      eventCenter.on('node:click', (args) => {
        this.nodeClick = args.data
        this.$nextTick(() => {
          this.$refs.propertySetting.show()
        })
      })

      eventCenter.on('edge:click', (args) => {
        this.nodeClick = args.data
        const nodeModel = this.lf.getNodeModelById(this.nodeClick.sourceNodeId);
        this.skipConditionShow = nodeModel.type === 'serial'
        this.$nextTick(() => {
          this.$refs.propertySetting.show(nodeModel.nodeType === 'serial')
        })
      })

      eventCenter.on('edge:add', (args) => {
        this.lf.changeEdgeType(args.data.id, 'skip')
        // 修改边类型
        this.lf.setProperties(args.data.id, {
          skipType: 'PASS'
        })
      })

      eventCenter.on('blank:click', (args) => {
        this.nodeClick = null
        this.$nextTick(() => {
          this.$refs.propertySetting.handleClose()
        })
      })
    },
    /** 关闭按钮 */
    close() {
      const obj = { path: "/flow/definition", query: { t: Date.now(), pageNum: this.$route.query.pageNum } };
      this.$tab.closeOpenPage(obj);
    },
  }
};
</script>

<style scoped>
.container {
  width: 100%;
  height: 800px;
}
</style>
<style>
.lf-control-see {
  background-image: url('');
}

.lf-control-save {
  background-image: url('');
}
.lf-control-clear {
  background-image:url('');
}
</style>
